﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Web.UI.WebControls;
using FortuneCookie.EPiServer.SearchAndReplace.Configuration;
using FortuneCookie.EPiServer.SearchAndReplace.Data;
using EPiServer;
using EPiServer.Configuration;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.PlugIn;
using EPiServer.UI.Edit.PageCompare.Plugin;
using EPiServer.UI.WebControls;
using EPiServer.Web.WebControls;

namespace FortuneCookie.EPiServer.SearchAndReplace
{

    /// <summary>
    /// Search and replace plugin class
    /// </summary>
    [GuiPlugIn(
        DisplayName = "Search and Replace",
        Description = "Searches and replaces text throughout the site.",
        Area = PlugInArea.EditPanel,
        SortIndex = 10000,
        Url = "~/Templates/Plugins/SearchAndReplace.ascx")]
    public class SearchAndReplacePlugin : UserControlBase, ICustomPlugInLoader
    {

        #region Members

        private bool _showSelectAllApproveBox;
        private bool _showSelectAllRollbackBox;

        #endregion Members

        #region Controls

        protected Literal StylesLiteral;
        protected Panel panMessage;
        protected Literal litMessage;
        protected PlaceHolder AreYouSurePlaceHolder;
        protected Button GoButton;
        protected PlaceHolder AddButtonPlaceHolder;
        protected Button AddButton;
        protected HiddenField Mode;
        protected Panel DefaultPanel;
        protected Repeater SummaryRepeater;
        protected Panel CreatePanel;
        protected HiddenField FindAndReplaceId;
        protected InputPageReference StartPageLinkUrl;
        protected RequiredFieldValidator StartPageRequiredFieldValidator;
        protected CheckBox StartPageOnlyCheckBox;
        protected PlaceHolder GlobalizationPlaceHolder;
        protected LanguageDropDownList LanguageDropDown;
        protected TextBox FindTextBox;
        protected RequiredFieldValidator FindRequiredFieldValidator;
        protected TextBox ReplaceTextBox;
        protected CheckBox MatchCaseCheckBox;
        protected CheckBox SearchWithinWordsCheckBox;
        protected PlaceHolder DynamicPropertiesPlaceHolder;
        protected PlaceHolder ProgressPlaceHolder;
        protected Literal ProgressTypeLiteral;
        protected Literal ProgressImageLiteral;
        protected PlaceHolder ApproveButtonPlaceHolder;
        protected PlaceHolder RollbackButtonPlaceHolder;
        protected CheckBox UpdateDynamicPropertiesCheckBox;
        protected Button PreGoButton;
        protected Button DeleteButton;
        protected Button ApproveButton;
        protected Button RollbackButton;
        protected Button CancelButton;
        protected Button CancelButton2;
        protected Button ViewButton;
        protected Panel ViewPanel;
        protected Literal StartPageLiteral;
        protected Literal StartPageOnlyLiteral;
        protected Literal LanguageBranchLiteral;
        protected Literal FindLiteral;
        protected Literal ReplaceLiteral;
        protected Literal MatchCaseLiteral;
        protected Literal SearchWithinWordsLiteral;
        protected Literal CompletedLiteral;
        protected Literal CreatedLiteral;
        protected Literal CreatedByLiteral;
        protected Literal PagesAffectedLiteral;
        protected Literal DynamicPropertiesAffectedLiteral;
        protected Literal ErrorsLiteral;
        protected PlaceHolder DynamicPropertiesPlaceHolder2;
        protected Literal UpdateDynamicPropertiesLiteral;
        protected Repeater PagesRepeater;
        protected Repeater DynamicPropertiesRepeater;
        protected Repeater ErrorsRepeater;
        protected Panel PreviewArea;
        protected ToolButton ShowVersionList;
        protected TabStrip ActionTab;
        protected Literal PublishedLiteral;
        protected Literal RolledbackLiteral;
        protected Literal NoDynamicPropertiesFoundLiteral;
        protected Literal NoPagesFoundLiteral;
        protected PlaceHolder DeleteButtonPlaceHolder;
        protected Tab PagesTab;
        protected Tab DynamicPropertiesTab;
        protected Tab ErrorsTab;
        protected PageComparePlugin epidiffcontrol;
        protected PlaceHolder EPiDiffPlaceHolder;

        #endregion Controls

        #region Properties

        private bool AllowUpdatingOfDynamicProperties
        {
            get
            {
                return ConfigurationHelper.AllowUpdatingOfDynamicProperties;
            }
        }

        private bool GlobalizedSite
        {
            get
            {
                return Settings.Instance.UIShowGlobalizationUserInterface;
            }
        }

        #endregion Properties

        #region Event handlers

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            PageLoadController();
            DataBind();
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            ShowHidePanels();
        }

        protected void AddButton_Click(object sender, EventArgs e)
        {
            Create();
        }

        protected void GoButton_Click(object sender, EventArgs e)
        {
            Go();
        }

        protected void PreGoButton_Click(object sender, EventArgs e)
        {
            VerifyGo();
        }

        protected void DeleteButton_Click(object sender, EventArgs e)
        {
            Guid id = new Guid(FindAndReplaceId.Value);
            Delete(id);
        }

        protected void DeleteButton2_Click(object sender, EventArgs e)
        {
            ToolButton imageButton = sender as ToolButton;
            Guid id = new Guid(imageButton.CommandArgument);
            Delete(id);
        }

        protected void CancelButton_Click(object sender, EventArgs e)
        {
            Cancel();
        }

        protected void ApproveButton_Click(object sender, EventArgs e)
        {
            Approve();
        }

        protected void RollbackButton_Click(object sender, EventArgs e)
        {
            Rollback();
        }

        protected void ViewButton_Click(object sender, EventArgs e)
        {
            View(new Guid(FindAndReplaceId.Value));
        }

        protected void BackButton_Click(object sender, EventArgs e)
        {
            Back();
        }

        protected void SelectButton_Click(object sender, EventArgs e)
        {
            Guid id = new Guid(((ToolButton)sender).CommandArgument);
            View(id);
        }

        protected void CompareButton_Click(object sender, EventArgs e)
        {
            Compare(((ToolButton)sender).CommandArgument);
        }

        protected void SummaryRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Header && ConfigurationHelper.AllowDeletionOfSearchAndReplaces)
            {
                e.Item.FindControl("DeleteHeaderPlaceHolder").Visible = true;
                return;
            }

            if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
                return;

            SearchAndReplace searchAndReplace = e.Item.DataItem as SearchAndReplace;

            ((ToolButton)e.Item.FindControl("SelectButton")).CommandArgument = searchAndReplace.Id.ToString();


            if (ConfigurationHelper.AllowDeletionOfSearchAndReplaces)
            {
                e.Item.FindControl("DeletePlaceHolder").Visible = true;
                ((ToolButton)e.Item.FindControl("DeleteButton")).CommandArgument = searchAndReplace.Id.ToString();
            }

            string startPageUrl = searchAndReplace.StartPage.Trim();
            ((Literal) e.Item.FindControl("StartPageLiteral")).Text = SearchAndReplaceHelper.GetPageDisplayValue(startPageUrl, searchAndReplace.LanguageBranch);
        }

        protected void PagesRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Header)
            {
                if (!_showSelectAllApproveBox)
                    e.Item.FindControl("ApprovePlaceHolder").Visible = false;

                if (!_showSelectAllRollbackBox)
                    e.Item.FindControl("RollbackPlaceHolder").Visible = false;

                return;
            }


            if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
                return;

            Page page = e.Item.DataItem as Page;
            bool rolledBack = SearchAndReplaceHelper.IsRolledBack(page);

            if (!_showSelectAllApproveBox)
                e.Item.FindControl("ApprovePlaceHolder").Visible = false;
            else
            {
                CheckBox checkBox = e.Item.FindControl("ApproveCheckBox") as CheckBox;
                checkBox.Attributes.Add("onclick", "javascript:SearchAndReplaceAreAllSelected('ApproveCheckBox');");
                checkBox.Visible = SearchAndReplaceHelper.CanPublish(page);
                checkBox.ID += string.Format("_{0}_{1}_{2}_{3}_{4}", page.Id, page.PageId, page.WorkId, page.LanguageBranch, page.PreviousWorkId);
            }

            if (!_showSelectAllRollbackBox)
                e.Item.FindControl("RollbackPlaceHolder").Visible = false;
            else
            {
                CheckBox checkBox = e.Item.FindControl("RollbackCheckBox") as CheckBox;
                checkBox.Attributes.Add("onclick", "javascript:SearchAndReplaceAreAllSelected('RollbackCheckBox');");
                checkBox.Visible = SearchAndReplaceHelper.CanRollback(page);
                checkBox.ID += string.Format("_{0}_{1}_{2}_{3}_{4}", page.Id, page.PageId, page.WorkId, page.LanguageBranch, page.PreviousWorkId);
            }

            // View link
            string url = ResolveUrl(Settings.Instance.UIUrl.ToString());

            if (!url.EndsWith("/"))
                url += "/";

            url += string.Format("edit/EditPanel.aspx?id={0}_{1}", page.PageId, page.WorkId);
            Literal viewLiteral = ((Literal)e.Item.FindControl("ViewLiteral"));
            viewLiteral.Text = !rolledBack ? string.Format(viewLiteral.Text, url, LanguageHelper.Translate("/searchAndReplacePlugin/view")) : string.Empty;

            // page name
            ((Literal)e.Item.FindControl("PageNameLiteral")).Text = SearchAndReplaceHelper.GetPageDisplayValue(page.PageId.ToString(), page.LanguageBranch);

            // language
            string language = page.LanguageBranch;
            string languageImage = string.Empty;
            LanguageBranch languageBranch = LanguageBranch.ListAll().Find(current => current.LanguageID == page.LanguageBranch);

            if (languageBranch != null)
            {
                languageImage = languageBranch.ResolvedIconPath;
                language = languageBranch.Name;
            }

            Literal languageLiteral = ((Literal)e.Item.FindControl("LanguageLiteral"));
            languageLiteral.Text = string.Format(languageLiteral.Text, language, languageImage);

            // Compare button
            ToolButton compareButton = e.Item.FindControl("CompareButton") as ToolButton;
            Page previousPage = new Page();
            previousPage.LanguageBranch = page.LanguageBranch;
            previousPage.PageId = page.PageId;
            previousPage.WorkId = page.PreviousWorkId;


            if (page.PreviousWorkId == page.WorkId || SearchAndReplaceHelper.IsRolledBack(page) || SearchAndReplaceHelper.IsRolledBack(previousPage))
                compareButton.Visible = false;
            else
                compareButton.CommandArgument = string.Format("{3}_{0}_{1}:{0}_{2}", page.PageId, page.PreviousWorkId, page.WorkId, page.LanguageBranch);

            // published
            ((Literal)e.Item.FindControl("PublishedLiteral")).Text = GetBooleanDisplayValue(SearchAndReplaceHelper.IsPublished(page));

            // rolledback
            Literal rolledbackLiteral = ((Literal)e.Item.FindControl("RolledbackLiteral"));
            rolledbackLiteral.Text = GetBooleanDisplayValue(rolledBack);

            if (rolledBack)
                rolledbackLiteral.Text += "/" + LanguageHelper.Translate("/searchAndReplacePlugin/replaced");
        }

        protected void DynamicPropertiesRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
                return;

            DynamicProperty dynamicProperty = e.Item.DataItem as DynamicProperty;
            Page page = new Page
                            {
                                PageId = dynamicProperty.PageId,
                                WorkId = dynamicProperty.WorkId,
                                LanguageBranch = dynamicProperty.LanguageBranch
                            };
            bool rolledBack = SearchAndReplaceHelper.IsRolledBack(page);

            // View link
            string url = ResolveUrl(Settings.Instance.UIUrl.ToString());

            if (!url.EndsWith("/"))
                url += "/";

            url += string.Format("edit/EditDynProp.aspx?id={0}_{1}", dynamicProperty.PageId, dynamicProperty.WorkId);
            Literal viewLiteral = ((Literal)e.Item.FindControl("ViewLiteral"));

            viewLiteral.Text = !rolledBack ? string.Format(viewLiteral.Text, url, LanguageHelper.Translate("/searchAndReplacePlugin/view")) : string.Empty;

            // page name
            ((Literal)e.Item.FindControl("PageNameLiteral")).Text = SearchAndReplaceHelper.GetPageDisplayValue(dynamicProperty.PageId.ToString(), dynamicProperty.LanguageBranch);

            // property name
            ((Literal)e.Item.FindControl("PropertyNameLiteral")).Text = dynamicProperty.PropertyName;

            // language
            string language = dynamicProperty.LanguageBranch;
            string languageImage = string.Empty;
            LanguageBranch languageBranch = LanguageBranch.ListAll().Find(current => current.LanguageID == dynamicProperty.LanguageBranch);

            if (languageBranch != null)
            {
                languageImage = languageBranch.ResolvedIconPath;
                language = languageBranch.Name;
            }

            Literal languageLiteral = ((Literal)e.Item.FindControl("LanguageLiteral"));
            languageLiteral.Text = string.Format(languageLiteral.Text, language, languageImage);
        }

        protected void ErrorsRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
                return;

            Error error = e.Item.DataItem as Error;
            Page page = new Page
            {
                PageId = error.PageId,
                WorkId = error.WorkId,
                LanguageBranch = error.LanguageBranch
            };
            bool rolledBack = SearchAndReplaceHelper.IsRolledBack(page);

            // View link
            string url = ResolveUrl(Settings.Instance.UIUrl.ToString());

            if (!url.EndsWith("/"))
                url += "/";

            if (error.PageProperty)
                url += string.Format("edit/EditPanel.aspx?id={0}_{1}", page.PageId, page.WorkId);
            else
                url += string.Format("edit/EditDynProp.aspx?id={0}_{1}", error.PageId, error.WorkId);
            Literal viewLiteral = ((Literal)e.Item.FindControl("ViewLiteral"));

            viewLiteral.Text = !rolledBack ? string.Format(viewLiteral.Text, url, LanguageHelper.Translate("/searchAndReplacePlugin/view")) : string.Empty;

            // page name
            ((Literal)e.Item.FindControl("PageNameLiteral")).Text = SearchAndReplaceHelper.GetPageDisplayValue(error.PageId.ToString(), error.LanguageBranch);

            // property name
            ((Literal)e.Item.FindControl("PropertyNameLiteral")).Text = error.PropertyName;

            // language
            string language = error.LanguageBranch;
            string languageImage = string.Empty;
            LanguageBranch languageBranch = LanguageBranch.ListAll().Find(current => current.LanguageID == error.LanguageBranch);

            if (languageBranch != null)
            {
                languageImage = languageBranch.ResolvedIconPath;
                language = languageBranch.Name;
            }

            Literal languageLiteral = ((Literal)e.Item.FindControl("LanguageLiteral"));
            languageLiteral.Text = string.Format(languageLiteral.Text, language, languageImage);

            // error message
            Literal errorMessageLiteral = ((Literal)e.Item.FindControl("ErrorMessageLiteral"));
            errorMessageLiteral.Text = Server.HtmlEncode(error.ErrorMessage);
        }

        #endregion Event handlers

        #region Methods

        private void PageLoadController()
        {
            epidiffcontrol = Page.LoadControl(UriSupport.ResolveUrlFromUIBySettings("edit/PageCompare/Plugin/PageComparePlugin.ascx")) as PageComparePlugin;
            EPiDiffPlaceHolder.Controls.Add(epidiffcontrol);
            ProgressPlaceHolder.Visible = false;

            if (Page.Header != null)
            {
                Literal literal = new Literal { Text = StylesLiteral.Text };
                literal.Text = literal.Text.Replace("#FINDANDREPLACECLIENTID#", FindAndReplaceId.ClientID);
                literal.Text = literal.Text.Replace("#VIEWBUTTONCLIENTID#", ViewButton.ClientID);
                literal.Text = literal.Text.Replace("#SELECTATLEASTONEPAGE#", LanguageHelper.Translate("/searchAndReplacePlugin/selectAtLeastOnePage"));               
                literal.Text = literal.Text.Replace("#PROGRESSREFRESHRATE#", ConfigurationHelper.ProgressRefreshRate.ToString());
                ProgressImageLiteral.Text = string.Format(ProgressImageLiteral.Text, Page.ClientScript.GetWebResourceUrl(typeof(DynamicProperty), "FortuneCookie.EPiServer.SearchAndReplace.Templates.Plugins.SearchAndReplaceProgress.gif"));
                Page.Header.Controls.Add(literal);
            }

            // If we are posting back and a tab has been clicked set mode back to 1
            if (IsPostBack)
            {
                if (Request.Form["__EVENTARGUMENT"] != null && Request.Form["__EVENTARGUMENT"].Equals("TabClicked"))
                    Mode.Value = "1";

                if (Mode.Value == "3")
                {
                    IDataHelper dataHelper = DataHelperFactory.CreateDataHelper();
                    PopulateView(dataHelper.GetById(new Guid(FindAndReplaceId.Value)));
                }
            }

            AreYouSurePlaceHolder.Visible = false;
            DynamicPropertiesPlaceHolder.Visible = ConfigurationHelper.AllowUpdatingOfDynamicProperties;

            if (Mode.Value == "1")
                PopulateSummaryTable();

            if (Mode.Value != "2")
                LanguageDropDown.SelectedLanguage = string.Empty;                
        }

        private void Create()
        {
            Mode.Value = "2";
            PopulteControls(new SearchAndReplace());
            FindAndReplaceId.Value = string.Empty;
        }

        private void View(Guid id)
        {
            Mode.Value = "3";
            IDataHelper dataHelper = DataHelperFactory.CreateDataHelper();
            ViewPanel.Visible = true;
            DeleteButtonPlaceHolder.Visible = false;//ConfigurationHelper.AllowDeletionOfSearchAndReplaces;
            PopulateView(dataHelper.GetById(id));
            FindAndReplaceId.Value = id.ToString();
        }

        private void Compare(string commandArgument)
        {
            string languageBranch = commandArgument.Substring(0, commandArgument.IndexOf("_"));
            commandArgument = commandArgument.Substring(commandArgument.IndexOf("_") + 1);
            string[] versions = commandArgument.Split(new[] {':'}, StringSplitOptions.RemoveEmptyEntries);
            int pageId = int.Parse(versions[0].Substring(0, versions[0].IndexOf("_")));
            int workId = int.Parse(versions[0].Substring(versions[0].IndexOf("_") + 1));
            PageReference previousPageReference = new PageReference(pageId, workId);
            workId = int.Parse(versions[1].Substring(versions[1].IndexOf("_") + 1));
            PageReference currentPageReference = new PageReference(pageId, workId);
            Compare(previousPageReference, currentPageReference, languageBranch);
            Mode.Value = "4";
        }
        
        private void VerifyGo()
        {
            if (!Page.IsValid)
                return;

            AreYouSurePlaceHolder.Visible = true;
        }

        private void Go()
        {
            if (!Page.IsValid)
                return;

            ProgressPlaceHolder.Visible = true;
            ProgressTypeLiteral.Text = "0";
            SearchAndReplace searchAndReplace = new SearchAndReplace { Id = Guid.NewGuid() };
            CollectPageValues(searchAndReplace);
            IDataHelper dataHelper = DataHelperFactory.CreateDataHelper();
            dataHelper.Update(searchAndReplace);
            SearchAndReplaceHelper.SearchAndReplace(searchAndReplace);
            FindAndReplaceId.Value = searchAndReplace.Id.ToString();
        }

        private void CollectPageValues(SearchAndReplace searchAndReplace)
        {
            searchAndReplace.Created = DateTime.Now;
            searchAndReplace.CreatedBy = Page.User.Identity.Name;
            searchAndReplace.StartPage = StartPageLinkUrl.ValueControl.Value.Trim();
            searchAndReplace.StartPageOnly = !StartPageOnlyCheckBox.Checked;
            searchAndReplace.LanguageBranch = LanguageDropDown.SelectedLanguage;
            searchAndReplace.Find = FindTextBox.Text;
            searchAndReplace.Replace = ReplaceTextBox.Text;
            searchAndReplace.MatchCase = MatchCaseCheckBox.Checked;
            searchAndReplace.SearchWithinWords = SearchWithinWordsCheckBox.Checked;
            searchAndReplace.UpdateDynamicProperties = UpdateDynamicPropertiesCheckBox.Checked;
        }

        private void Cancel()
        {
            Mode.Value = "1";
        }

        private void PopulteControls(SearchAndReplace searchAndReplace)
        {
            StartPageOnlyCheckBox.Checked = searchAndReplace.StartPageOnly;
            FindTextBox.Text = searchAndReplace.Find;
            ReplaceTextBox.Text = searchAndReplace.Replace;
            MatchCaseCheckBox.Checked = searchAndReplace.MatchCase;
            SearchWithinWordsCheckBox.Checked = searchAndReplace.SearchWithinWords;
            UpdateDynamicPropertiesCheckBox.Checked = searchAndReplace.UpdateDynamicProperties;

            if (!string.IsNullOrEmpty(searchAndReplace.StartPage) && SearchAndReplaceHelper.IsInt32(searchAndReplace.StartPage))
            {
                PageReference pageReference = new PageReference(int.Parse(searchAndReplace.StartPage));
                StartPageLinkUrl.PageLink = pageReference;
            }
        }

        private string GetBooleanDisplayValue(bool value)
        {
            return value ? LanguageHelper.Translate("/searchAndReplacePlugin/yes") : LanguageHelper.Translate("/searchAndReplacePlugin/no");
        }

        private void PopulateView(SearchAndReplace searchAndReplace)
        {
            ActionTab.SetSelectedTab(0);
            StartPageLiteral.Text = SearchAndReplaceHelper.GetPageDisplayValue(searchAndReplace.StartPage, searchAndReplace.LanguageBranch);
            StartPageOnlyLiteral.Text = GetBooleanDisplayValue(!searchAndReplace.StartPageOnly);
            FindLiteral.Text = Server.HtmlEncode(searchAndReplace.Find);
            ReplaceLiteral.Text = Server.HtmlEncode(searchAndReplace.Replace);
            MatchCaseLiteral.Text = GetBooleanDisplayValue(searchAndReplace.MatchCase);
            SearchWithinWordsLiteral.Text = GetBooleanDisplayValue(searchAndReplace.SearchWithinWords);
            UpdateDynamicPropertiesLiteral.Text = GetBooleanDisplayValue(searchAndReplace.UpdateDynamicProperties);
            CreatedLiteral.Text = searchAndReplace.Created.ToString("dd/MM/yyyy HH:mm:ss");
            CreatedByLiteral.Text = searchAndReplace.CreatedBy;
            CompletedLiteral.Text = GetBooleanDisplayValue(searchAndReplace.Completed);
            PagesAffectedLiteral.Text = searchAndReplace.Pages.Count.ToString();
            DynamicPropertiesAffectedLiteral.Text = searchAndReplace.DynamicProperties.Count.ToString();
            ErrorsLiteral.Text = searchAndReplace.Errors.Count.ToString();

            PagesTab.Text = LanguageHelper.Translate("/searchAndReplacePlugin/pages") + (searchAndReplace.Pages.Count > 0 ? string.Format(" ({0})", searchAndReplace.Pages.Count) : string.Empty);
            DynamicPropertiesTab.Text = LanguageHelper.Translate("/searchAndReplacePlugin/dynamicProperties") + (searchAndReplace.DynamicProperties.Count > 0 ? string.Format(" ({0})", searchAndReplace.DynamicProperties.Count) : string.Empty);
            ErrorsTab.Text = LanguageHelper.Translate("/searchAndReplacePlugin/errors") + (searchAndReplace.Errors.Count > 0 ? string.Format(" ({0})", searchAndReplace.Errors.Count) : string.Empty);

            // set language branch
            string language = searchAndReplace.LanguageBranch;

            if (!string.IsNullOrEmpty(language))
            {
                string languageImage = string.Empty;
                string languageToCompare = language;
                LanguageBranch languageBranch = LanguageBranch.ListAll().Find(current => current.LanguageID == languageToCompare);

                if (languageBranch != null)
                {
                    languageImage = languageBranch.ResolvedIconPath;
                    language = languageBranch.Name;
                }

                LanguageBranchLiteral.Text = string.Format(LanguageBranchLiteral.Text, language, languageImage);
            }
            else
                LanguageBranchLiteral.Text = LanguageHelper.Translate("/searchAndReplacePlugin/all");

            // Bind the pages repeater
            _showSelectAllApproveBox = false;
            _showSelectAllRollbackBox = false;
            PagesRepeater.Visible = searchAndReplace.Pages.Count > 0;
            DynamicPropertiesRepeater.Visible = searchAndReplace.DynamicProperties.Count > 0;
            ErrorsRepeater.Visible = searchAndReplace.Errors.Count > 0;
            NoPagesFoundLiteral.Visible = !PagesRepeater.Visible;
            NoDynamicPropertiesFoundLiteral.Visible = !DynamicPropertiesRepeater.Visible;

            foreach (Page page in searchAndReplace.Pages)
            {
                if (!_showSelectAllApproveBox && SearchAndReplaceHelper.CanPublish(page))
                    _showSelectAllApproveBox = true;

                if (!_showSelectAllRollbackBox && SearchAndReplaceHelper.CanRollback(page))
                    _showSelectAllRollbackBox = true;
            }

            if (PagesRepeater.Visible)
            {
                PagesRepeater.DataSource = searchAndReplace.Pages;
                PagesRepeater.DataBind();
            }

            if (DynamicPropertiesRepeater.Visible)
            {
                DynamicPropertiesRepeater.DataSource = searchAndReplace.DynamicProperties;
                DynamicPropertiesRepeater.DataBind();
            }

            if (ErrorsRepeater.Visible)
            {
                ErrorsRepeater.DataSource = searchAndReplace.Errors;
                ErrorsRepeater.DataBind();
            }

            // Enable buttons
            if (ConfigurationHelper.DisableApproveAndRollbackButtonsIfSearchNotCompleted && !searchAndReplace.Completed)
            {
                ApproveButtonPlaceHolder.Visible = false;
                RollbackButtonPlaceHolder.Visible = false;
                return;
            }

            bool canPublish = false;
            bool canRollback = false;

            foreach (Page page in searchAndReplace.Pages)
            {
                if (SearchAndReplaceHelper.CanPublish(page))
                    canPublish = true;

                if (SearchAndReplaceHelper.CanRollback(page))
                    canRollback = true;
            }

            ApproveButtonPlaceHolder.Visible = canPublish;
            RollbackButtonPlaceHolder.Visible = canRollback;
        }

        private void PopulateSummaryTable()
        {
            IDataHelper dataHelper = DataHelperFactory.CreateDataHelper();
            List<SearchAndReplace> searchAndReplaces = dataHelper.GetAll();
            SummaryRepeater.DataSource = searchAndReplaces;
            SummaryRepeater.DataBind();
        }

        private void ShowHidePanels()
        {
            DefaultPanel.Visible = Mode.Value == "1";
            CreatePanel.Visible = Mode.Value == "2";
            ViewPanel.Visible = Mode.Value == "3";
            AddButtonPlaceHolder.Visible = Mode.Value == "1";
            PreviewArea.Visible = Mode.Value == "4";

            DynamicPropertiesPlaceHolder.Visible = AllowUpdatingOfDynamicProperties;
            DynamicPropertiesPlaceHolder2.Visible = AllowUpdatingOfDynamicProperties;
            GlobalizationPlaceHolder.Visible = GlobalizedSite;

            if (Mode.Value == "1")
            {
                if (SummaryRepeater.DataSource == null)
                    PopulateSummaryTable();

                StartPageLinkUrl.PageLink = null;
                StartPageLinkUrl.DisplayControl.Text = string.Empty;

                if (StartPageLinkUrl.ValueControl != null)
                    StartPageLinkUrl.ValueControl.Value = string.Empty;
            }
        }

        private void Back()
        {
            View(new Guid(FindAndReplaceId.Value));
        }

        private void Approve()
        {
            ProgressPlaceHolder.Visible = true;
            ProgressTypeLiteral.Text = "1";
            View(new Guid(FindAndReplaceId.Value));
            SearchAndReplaceHelper.Publish(GetSelectedPages("ApproveCheckBox"));
        }

        private void Rollback()
        {
            ProgressPlaceHolder.Visible = true;
            ProgressTypeLiteral.Text = "2";
            View(new Guid(FindAndReplaceId.Value));
            SearchAndReplaceHelper.Rollback(GetSelectedPages("RollbackCheckBox"));
        }

        private void Delete(Guid id)
        {
            IDataHelper dataHelper = DataHelperFactory.CreateDataHelper();
            SearchAndReplace searchAndReplace = dataHelper.GetById(id);
            dataHelper.Delete(searchAndReplace);
            Mode.Value = "1";
            PopulateSummaryTable();
        }

        private List<Page> GetSelectedPages(string checkBoxName)
        {
            List<Page> pages = new List<Page>();
            string controlName = "$" + checkBoxName;

            foreach (string key in Request.Form.AllKeys)
            {
                if (!key.Contains(controlName))
                    continue;

                string[] keyParts = key.Substring(key.IndexOf(controlName) + controlName.Length).Split(new[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
                pages.Add(new Page 
                                { 
                                    Id = new Guid(keyParts[0]), 
                                    SearchAndReplaceId = new Guid(FindAndReplaceId.Value),
                                    PageId = int.Parse(keyParts[1]), 
                                    WorkId = int.Parse(keyParts[2]), 
                                    LanguageBranch = keyParts[3],
                                    PreviousWorkId = int.Parse(keyParts[4])
                                });
            }

            return pages;
        }

        private DropDownList GetVersioningDropDownList(PageComparePlugin epidiffcontrol, string propertyName)
        {
            DropDownList dropDown = null;

            FieldInfo fieldInfo = epidiffcontrol.GetType().GetField(propertyName, BindingFlags.Instance | BindingFlags.NonPublic);

            if (fieldInfo != null)
                dropDown = fieldInfo.GetValue(epidiffcontrol) as DropDownList;

            return dropDown;
        }

        private void Compare(PageReference page1, PageReference page2, string languageBranch)
        {
            // would usually call the method below but because the databind method uses the current page
            // this only works when using the version list so I am having to use some reflection to get
            // dropdowns and poplulate the values
            //epidiffcontrol.VersionLists_DataBind(page1, page2, languageBranch);
            
            DropDownList version1 = GetVersioningDropDownList(epidiffcontrol, "version1");
            DropDownList version2 = GetVersioningDropDownList(epidiffcontrol, "version2");
            version1.Items.Clear();
            version2.Items.Clear();
            version1.ClearSelection();
            version2.ClearSelection();

            PageVersionCollection versions = PageVersion.List(page1, languageBranch);
            for (int i = 0; i < versions.Count; i++)
            {
                PageVersion version = versions[i];

                if (!string.IsNullOrEmpty(languageBranch) && (version.LanguageBranch != languageBranch)) 
                    continue;

                object[] args = new object[] { ((i + 1)).ToString("0") + " " + version.LanguageBranch };
                version1.Items.Add(new ListItem(string.Format(CultureInfo.CurrentCulture, base.Translate("/epidiff/choose/version") + " {0}", args), version.ID.ToString()));
                object[] objArray2 = new object[1];
                objArray2[0] = ((i + 1)).ToString("0") + " " + version.LanguageBranch;
                version2.Items.Add(new ListItem(string.Format(CultureInfo.CurrentCulture, base.Translate("/epidiff/choose/version") + " {0}", objArray2), version.ID.ToString()));
            }

            if ((null != page1) || (null != page2))
            {
                version1.SelectedValue = page2.ToString();
                version2.SelectedValue = page1.ToString();
            }

            epidiffcontrol.StartEPiDiff(page1.ToString(), page2.ToString());
        }


        #endregion Methods

        #region ICustomPlugInLoader Members

        /// <summary>
        /// Gets the plugin descriptor
        /// </summary>
        /// <returns></returns>
        public PlugInDescriptor[] List()
        {
            // Check if we should show the plugin
            if (ConfigurationHelper.Enabled)
            {
                bool allowed = ConfigurationHelper.AllowedRoles.Contains("*");

                if (!allowed)
                {
                    if (ConfigurationHelper.AllowedRoles.Any(role => Page.User.IsInRole(role)))
                        allowed = true;
                }

                if (allowed)
                {
                    PlugInDescriptor descriptor = PlugInDescriptor.Load(GetType());
                    return new[] {descriptor};
                }
            }

            // Hide the plugin
            return new PlugInDescriptor[0];
        }

        #endregion ICustomPlugInLoader Members

    }
}
